﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Bson.Converters;

namespace Yozeev.Common.Extensions
{
    public static class ObjectExtension
    {
        public static object ConvertToSimpleType(this object value, Type destType)
        {
            object returnValue;
            if (destType.IsInstanceOfType(value) || (value == null))
            {
                return value;
            }

            if ((destType == typeof(bool) || destType == typeof(bool?)) 
                && IsValidBoolean(value.ToString()))
            {
                return value.ToBoolean();
            }

            if (destType == typeof(Decimal) || destType == typeof(Decimal?))
            {
                return value.ToDecimal();
            }

            if (destType.IsEnum)
            {
                try
                {
                    return Enum.ToObject(destType, value.ToInt32());
                }
                catch
                {
                    return Enum.Parse(destType, value.ToString());
                }
            }

            if (destType == typeof(DateTime) || destType == typeof(DateTime?))
                return value.ToDateTime();

            if (destType == typeof(Guid) || destType == typeof(Guid?))
            {
                return new Guid(value.ToString());
            }

            if (destType == typeof(System.Int64?))
            {
                return Convert.ToInt64(value);
            }

            TypeConverter converter = TypeDescriptor.GetConverter(destType);
            if (!converter.CanConvertTo(destType))
            {
                throw new InvalidOperationException("无法转换成类型：" + value.ToString() + "==>" + destType);
            }
            try
            {
                returnValue = converter.ConvertTo(null, null, value, destType);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("类型转换出错：" + value.ToString() + "==>" + destType, e);
            }
            return returnValue;
        }

        private static bool IsValidBoolean(string value)
        {
            string[] validStrings = { "0", "1", "true", "false", "t", "f" };
            return validStrings.Contains(value.ToLower());
        }

        public static DateTime ToDateTime(this object obj)
        {
            try
            {
                return Convert.ToDateTime(obj);
            }
            catch
            {
                throw new InvalidOperationException("无法转换成类型：" + obj.ToString() + "==> DateTime");
            }
        }

        public static Int32 ToInt32(this object obj)
        {
            return Convert.ToInt32(obj);
        }

        public static decimal ToDecimal(this object obj)
        {
            try
            {
                return Convert.ToDecimal(obj);
            }
            catch
            {
                return 0.00M;
            }
        }

        public static bool ToBoolean(this object value)
        {
            switch (value.ToString().ToLower())
            {
                case "1":
                case "t":
                case "true":
                    return true;
                case "0":
                case "f":
                case "false":
                    return false;
                default:
                    return false;
            }
        }

        public static Dictionary<string, string> ToDictionary(this object value)
        {
            Type t = value.GetType();
            Dictionary<string, string> result = new Dictionary<string, string>();
            foreach (var p in t.GetProperties())
            {
                result.Add(p.Name, p.GetValue(value).ToString());
            }
            return result;
        }
    }
}
